package com.mdh.EightStudy.javabase;

import java.util.ArrayList;
import java.util.List;

/**
 * @author mac
 * @date 2021/9/6 1:49 下午
 */
public class GenericStudy {
    public static void main(String[] args) {
        List<? extends Number> listNum = new ArrayList<>();
        List<String> listStr = new ArrayList<>();

        Class<? extends List> aClass = listNum.getClass();
        Class<? extends List> aClass1 = listStr.getClass();
        System.out.println(aClass == aClass1);
    }
}

/**
 * 泛型类
 *
 * @param <T>
 */
class FanxingCLass<T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public static void main(String[] args) {
        //由于泛型擦除的原因可以实现添加和获取
        FanxingCLass<String> fanxingCLass = new FanxingCLass<>();
        fanxingCLass.getT();
        fanxingCLass.setT("...");
    }
}

/**
 * 泛型接口
 * @param <T>
 */
interface FanxingInterface<T>{
    /**
     * 当前类有泛型的入参写法
     * @param t
     */
    public void methoda(T t);

    /**
     * 当前类有泛型的出参写法
     * @return
     */
    public T methodb();

    /**
     * 这里的T和类上的T类型不需要一致，这里的T是一个全新的T
     * @param t
     * @param <T>
     * @return
     */
    public <T> T methodc(T t);

}

/**
 * 类和接口能够设置泛型边界
 */
interface FanxingInterface1<T extends Number>{
    /**
     * 当前类不是泛型类，但方法的入参出参是泛型
     * E和T为了提高可读性，E表示element，T表示type
     * @param e
     * @param <E>
     */
    public <E> E methodc(E e);
    public <T> T method1(T t);

    /**
     * 给泛型设置边界只能在入参或者出参返回具体的带有泛型的类型才能设置边界
     * @param src
     */
    public void method2(List<? extends Number> src);
    public void method3(List<? super Number> src);
}

class FanxingInterfaceImpl<T> implements FanxingInterface<T>{

    @Override
    public void methoda(T t) {

    }

    @Override
    public T methodb() {
        return null;
    }

    @Override
    public <T> T methodc(T t) {
        return null;
    }
}

